package model

import (
	"encoding/base64"
	"encoding/json"
	"github.com/jinzhu/gorm"
	"github.com/spf13/viper"
	"loveserver/pkg/client/fabric"
	"loveserver/pkg/core/config"
	"time"
	"loveserver/pkg/core/entity/req/fabric/node"
	"math/rand"
	"log"
	"fmt"
)

//中心化
type WordsModel struct {
	gorm.Model
    Name string  `gorm:"not null;type :varchar(32)" json:"name"`
    Object string `gorm:"not null;type :varchar(32)" json:"object"`
	Title string `gorm:"not null;type :varchar(32)" json:"title"`
    Content string `gorm:"not null;type :varchar(500)" json:"content"`
	Summary string `gorm:"not null;type :varchar(32)" json:"summary"`
}

//真誓言上链
type SwearModel struct {
	SwearMan   string `json:"swearman"`
	SwearObject string `json:"swearobject"`
	SwearTitle string `json:"sweartitle"`
	SwearContent string `json:"swearcontent"`
}

type GetSwearModel struct {
	SwearMan   string `json:"swearman"`
}

type BCMessage struct {
	Body string
}

type QueryLocation struct {
	OrderId string `json:"orderid"`
}

// * 设置表名
func (words WordsModel) TableName() string {
	return "words"
}

// * 添加words到数据库
func (words WordsModel) Create() error  {
  return DB.Self.Create(&words).Error
}


// * 获取某一个誓言
func (words WordsModel) Get() (WordsModel, error) {
	return words, DB.Self.First(&words, words.ID).Error
}

// * 获取所有的誓言
func (words WordsModel) GetAll() (uint64, []WordsModel, error) {

	var thewords []WordsModel
	var count uint64

	if err := DB.Self.Table(words.TableName()).Count(&count).Error; err != nil {
		return count, thewords, err
	}
	if err := DB.Self.Find(&thewords).Error; err != nil {
		return count, thewords, err
	}
	return count, thewords, nil

}

// * 删除某个shield
func (shield ShieldModel) Delete() error {
	return DB.Self.Delete(&shield).Error
}



//生成24位伪随机数int
// Returns an int >= min, < max
func randomInt(min, max int) int {
	return min + rand.Intn(max-min)
}


// Generate a random string of A-Z chars with len = l
func RandomByte(len int) []byte {
	//将int转化为byte类型
	bytes := make([]byte, len)
	for i := 0; i < len; i++ {
		bytes[i] = byte(randomInt(65, 90))
	}
	// ms:= string(bytes)
	return bytes
}
//对随机数进行base64加密编码生成Nonce
func  Base64Encrypt(body []byte) string{
	encodeString := base64.StdEncoding.EncodeToString(body)
	return encodeString
}

//用户住址上链
func  SetLocation(message string ) (string, error) {
	//随机数nonce生成
	rand.Seed(time.Now().UnixNano())//放在最外层
	bytes:=RandomByte(24)
	nonce:=Base64Encrypt(bytes)

	//传入string
	var orderdata = []string {message}
	var  trans  node.TransReqDataBody
	trans.Args=orderdata
	trans.ChainCode=viper.GetString("bc.chaincode")
	trans.FuncName="set"     //链码功能名
	trans.Nonce=nonce
	client:=BCinit()
	res,err:=client.ReqChainCode(node.TransReqDataBody(trans))
	if err != nil {
		log.Fatal(err)
	}
	var messages BCMessage
	messages.Body=res.Body.CCRes.CCData
	return messages.Body,nil
}

//通过订单号查询用户住址
func  GetLocation(data string) (string, error) {
	rand.Seed(time.Now().UnixNano())//放在最外层
	bytes:=RandomByte(24)
	nonce:=Base64Encrypt(bytes)

	var  trans  node.TransReqDataBody
	var messages BCMessage
	var  test1 =[]string {data}
	trans.Args=test1   //通过key查values
	trans.ChainCode=viper.GetString("bc.chaincode")
	trans.FuncName="get"
	trans.Nonce=nonce
	//fbclient :=fabric.FabricClient{}
	client:=BCinit()
	res,err  := client.ReqChainCode(node.TransReqDataBody(trans))
	if err != nil {
		log.Fatal(err)
	}
	messages.Body=res.Body.CCRes.CCData
	return messages.Body,nil
}


func BCinit() *fabric.FabricClient {

	api := viper.GetString("bc.api")     //PCN gateway address
	userCode := viper.GetString("bc.userCode") //user code
	appCode := viper.GetString("bc.appCode")  //DApp code
	puk := "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEV5+GtbQNzwfPsMfVIFNBg3xgRuwV\n2RDS+Rjd72F6qXGwrb8QLSDUitNinENWuowAEsu/U9GsfSn0A48xlRTfSg==\n-----END PUBLIC KEY-----"      //public key
	prk := "-----BEGIN PRIVATE KEY-----\nMIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgVbS8svrC3sdFgIFW\nUoLfczfjCjq0z7fGTSFfqMkjssChRANCAARXn4a1tA3PB8+wx9UgU0GDfGBG7BXZ\nENL5GN3vYXqpcbCtvxAtINSK02KcQ1a6jAASy79T0ax9KfQDjzGVFN9K\n-----END PRIVATE KEY-----"      //private key
	mspDir := ""   //cert storage directory
	cert := ""     //certS


	config, err := config.NewConfig(api, userCode, appCode, puk, prk, mspDir, cert)
	if err != nil {
		log.Fatal(err)
	}
	client,err:=fabric.InitFabricClient(config)
	return client
}

//誓言上链
func  SetSwear(swear SwearModel) (string, error) {
	//随机数nonce生成
	rand.Seed(time.Now().UnixNano())//放在最外层
	bytes:=RandomByte(24)
	nonce:=Base64Encrypt(bytes)

	//!!!!!关键转换步骤  先解析成[]byte  再 转换为string  这样保留了键值
	word, err := json.Marshal(swear)
	if err!=nil{
		fmt.Println("转换失败")
	}
	var  words =[]string {string(word)}
	var  trans  node.TransReqDataBody
	trans.Args=words
	trans.ChainCode=viper.GetString("bc.chaincode")
	trans.FuncName="set"     //链码功能名
	trans.Nonce=nonce
	client:=BCinit()
	res,err:=client.ReqChainCode(node.TransReqDataBody(trans))
	if err != nil {
		log.Fatal(err)
	}
	var messages BCMessage
	messages.Body=res.Body.CCRes.CCData
	return messages.Body,nil
}

//誓言查询
func  GetSwear(swearname string) (string, error) {
	//随机数nonce生成
	rand.Seed(time.Now().UnixNano())//放在最外层
	bytes:=RandomByte(24)
	nonce:=Base64Encrypt(bytes)

	var  test =[]string {swearname}
	var  trans  node.TransReqDataBody
	trans.Args=test
	trans.ChainCode=viper.GetString("bc.chaincode")
	trans.FuncName="getSwear"    //链码功能名
	trans.Nonce=nonce
	client:=BCinit()
	res,err:=client.ReqChainCode(node.TransReqDataBody(trans))
	if err != nil {
		log.Fatal(err)
	}
	var messages BCMessage
	messages.Body=res.Body.CCRes.CCData
	return messages.Body,nil
}